package com.wql.study;
//package com.wql.mybatis.study;
//
//import java.sql.Connection;
//import java.util.List;
//import java.util.Properties;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//
//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;
//import org.apache.ibatis.builder.SqlSourceBuilder;
//import org.apache.ibatis.executor.statement.StatementHandler;
//import org.apache.ibatis.mapping.SqlSource;
//import org.apache.ibatis.plugin.Interceptor;
//import org.apache.ibatis.plugin.Intercepts;
//import org.apache.ibatis.plugin.Invocation;
//import org.apache.ibatis.plugin.Plugin;
//import org.apache.ibatis.plugin.Signature;
//import org.apache.ibatis.reflection.MetaObject;
//import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
//import org.apache.ibatis.reflection.factory.ObjectFactory;
//import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
//import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
//import org.apache.ibatis.session.Configuration;
//
//import com.cool.app.util.TableInfoUtils;
//
///**
// * ibatis 插件，对于测试用户来说，如果存在_temp结尾的表，则操作改表，否则操作原来的表
// * 
// * @author wuqinglong
// * @date 2015年1月5日 上午11:32:56
// */
//@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
//public class SpecialUserSqlHandlerInterceptor implements Interceptor {
//
//	private static Log log = LogFactory.getLog(SpecialUserSqlHandlerInterceptor.class);
//
//	private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
//
//	private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
//
//	private static Pattern pattern = null;
//
//	@Override
//	public Object intercept(Invocation invocation) throws Throwable {
//		if (!TokenThreadLocal.getUser().isSpecialUser())
//			return invocation.proceed();
//		StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
//		MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
//		// 分离代理对象链
//		while (metaStatementHandler.hasGetter("h")) {
//			Object object = metaStatementHandler.getValue("h");
//			metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
//		}
//		// 分离最后一个代理对象的目标类
//		while (metaStatementHandler.hasGetter("target")) {
//			Object object = metaStatementHandler.getValue("target");
//			metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
//		}
//		String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
//		Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
//		Object parameterObject = metaStatementHandler.getValue("delegate.boundSql.parameterObject");
//		if (originalSql != null) {
//			String newSql = "";
//			log.info("------SpecialUserSqlHandlerInterceptor sql before = " + originalSql);
//			Matcher matcher = getPattern().matcher(originalSql);
//			if (matcher.groupCount() > 0) {
//				newSql = matcher.replaceAll("$1_temp");
//			} else {
//				newSql = originalSql;
//			}
//			log.info("------SpecialUserSqlHandlerInterceptor sql after = " + newSql);
//			SqlSource sqlSource = buildSqlSource(configuration, newSql, parameterObject.getClass());
//			metaStatementHandler.setValue("delegate.boundSql.sql", sqlSource.getBoundSql(parameterObject).getSql());
//		}
//		statementHandler = (StatementHandler) metaStatementHandler.getOriginalObject();
//		statementHandler.prepare((Connection) invocation.getArgs()[0]);
//		return invocation.proceed();
//	}
//
//	@Override
//	public Object plugin(Object target) {
//		return Plugin.wrap(target, this);
//	}
//
//	@Override
//	public void setProperties(Properties properties) {
//
//	}
//
//	private synchronized Pattern getPattern() {
//		if (null != pattern)
//			return pattern;
//		List<String> list = TableInfoUtils.showTables();
//		StringBuilder sb = new StringBuilder("");
//		if (!list.isEmpty()) {
//			sb.append("(");
//			for (int i = 0, j = list.size(); i < j; i++) {
//				if (0 != i) {
//					sb.append("|");
//				}
//				sb.append("(?:\\b").append(list.get(i)).append("\\b)");
//			}
//			sb.append(")");
//		}
//		log.info("------SpecialUserSqlHandlerInterceptor------");
//		log.info("------SpecialUserSqlHandlerInterceptor tablename_regex_str = " + sb.toString());
//		return Pattern.compile(sb.toString(), Pattern.CASE_INSENSITIVE);
//	}
//
//	private SqlSource buildSqlSource(Configuration configuration, String originalSql, Class<?> parameterType) {
//		SqlSourceBuilder builder = new SqlSourceBuilder(configuration);
//		return builder.parse(originalSql, parameterType, null);
//	}
//
//}
